package ks.managers.game;

import java.util.Hashtable;

/**
 * Entity object representing information about a game.
 * 
 * @author Daphne Gorman
 * @author Harry Moreno
 * @author Christopher Page
 */
public class Game {
	
	protected int tableId;
	protected String plugin;
	protected int time;
	protected boolean newhand;
	protected boolean undo;
	protected boolean started;
	protected boolean finished;
	protected Hashtable<String, Integer> scores;
	protected Hashtable<String, Integer> wins;
	protected Hashtable<String, Integer> hands;
	
	/**
	 * The constructor.
	 * 
	 * @param i The id of the table that the game takes place on.
	 */
	public Game (int i) {
		this.tableId = i;
		this.plugin = null;
		this.time = 0;
		this.newhand = false;
		this.undo = false;
		this.started = false;
		this.finished = false;
		this.scores = new Hashtable<String, Integer>(0);
		this.wins = new Hashtable<String, Integer>(0);
		this.hands = new Hashtable<String, Integer>(0);
	}
	
	/**
	 * Resets the game.
	 */
	public void resetGame() {
		this.plugin = null;
		this.time = 0;
		this.newhand = false;
		this.undo = false;
		this.started = false;
		this.finished = false;
		this.scores = new Hashtable<String, Integer>(0);
		this.wins = new Hashtable<String, Integer>(0);
		this.hands = new Hashtable<String, Integer>(0);
	}
	
	/**
	 * Retrieves whether or not the game has started.
	 * 
	 * @return Whether or not the game has started.
	 */
	public boolean hasStarted() { return this.started; }
	
	/**
	 * Retrieves whether or not the game has finished.
	 * 
	 * @return Whether or not the game has finished.
	 */
	public boolean hasFinished() { return this.finished; }
	
	/**
	 * Retrieves the name of the plugin in use.
	 * 
	 * @return The name of the plugin in use.
	 */
	public String getPlugin() { return this.plugin; }
	
	/**
	 * Sets the name of the plugin in use.
	 * 
	 * @param p A name of a plugin.
	 */
	public void setPlugin(String p) { this.plugin = p; }
	
	/**
	 * Retrieves the time.
	 * 
	 * @return The time.
	 */
	public int getTime() { return this.time; }
	
	/**
	 * Sets the time.
	 * 
	 * @param t The time.
	 */
	public void setTime(int t) { this.time = t; }
	
	/**
	 * Retrieves whether or not newhand is allowed.
	 * 
	 * @return Whether or not newhand is allowed.
	 */
	public boolean getNewhand() { return this.newhand; }
	
	/**
	 * Sets whether or not newhand is allowed.
	 * 
	 * @param b Whether or not newhand is allowed.
	 */
	public void setNewhand(boolean b) { this.newhand = b; }
	
	/**
	 * Retrieves whether or not undo is allowed.
	 * 
	 * @return Whether or not undo is allowed.
	 */
	public boolean getUndo() { return this.undo; }
	
	/**
	 * Sets whether or not undo is allowed.
	 * 
	 * @param b Whether or not undo is allowed.
	 */
	public void setUndo(boolean b) { this.undo = b; }
	
	/**
	 * Adds a player to the game.
	 * 
	 * @param username The username of the player.
	 * @return True on success; false on failure.
	 */
	public boolean addPlayer (String username) {
		if (!this.started) {
			if (this.scores.containsKey(username))
				return true;
			this.scores.put(username, new Integer(0).intValue());
			this.wins.put(username, new Integer(0).intValue());
			this.hands.put(username, new Integer(0).intValue());
			return true;
		}
		return false;
	}
	
	/**
	 * Removes a player from the game.
	 * 
	 * @param username The player to remove.
	 */
	public void removePlayer (String username) {
		this.scores.remove(username); 
		this.wins.remove(username);
		this.hands.remove(username);
	}
	
	/**
	 * Updates the score, wins, and hands of the specified player.
	 * 
	 * @param username The username of the player.
	 * @param score The score of the player.
	 * @param wins The number of wins the player has.
	 * @param hands The number of hands the player has.
	 */
	public void updatePlayer (String username, int score, int wins, int hands) {
		if (this.started && this.scores.containsKey(username)) {
			this.scores.remove(username);
			this.scores.put(username, score);
			this.wins.remove(username);
			this.wins.put(username, wins);
			this.hands.remove(username);
			this.hands.put(username, hands);
		}
	}
	
	/**
	 * Retrieves the score of the given player.
	 * 
	 * @param username The username of the player.
	 * @return The score of the specified player.
	 */
	public int getScore(String username) {
		Integer temp = this.scores.get(username);
		if (temp == null)
			return -1;
		return temp.intValue();
	}
	
	/**
	 * Retrieves the wins of the given player.
	 * 
	 * @param username The username of the player.
	 * @return The wins of the specified player.
	 */
	public int getWins(String username) {
		Integer temp = this.wins.get(username);
		if (temp == null)
			return -1;
		return temp.intValue();
	}
	
	/**
	 * Retrieves the hands of the given player.
	 * 
	 * @param username The username of the player.
	 * @return The hands of the specified player.
	 */
	public int getHands(String username) {
		Integer temp = this.hands.get(username);
		if (temp == null)
			return -1;
		return temp.intValue();
	}
	
	/**
	 * Starts the game.
	 */
	public void startGame() { this.started = true; }
	
	/**
	 * Finishes the game.
	 */
	public void finishGame() { this.finished = true; }
}